<?php

namespace app\common\service;

class RSA
{
    private $privateKey;//私钥字符串
    private $privateKey_n = 'privateKey.pem';//私钥文件名
    private $publicKey;//公钥字符串
    private $publicKey_n = 'publicKey.pem';//公钥
    private $path;//存放私钥文件夹名

    public function __construct($filePath =  '../runtime/RSA/')
    {
        $this->path = $filePath;
        file_exists($this->path . $this->privateKey_n) ? $this->getKey() : $this->createKeys();
    }

    /**
     *  获取钥匙
     */
    private function getKey () {
        $this->privateKey = file_get_contents($this->path .  $this->privateKey_n);
        $this->publicKey = file_get_contents($this->path .  $this->publicKey_n);
    }

    /**
     * 创建 密钥对
     */
    private function createKeys ()
    {
        $resource = openssl_pkey_new(['private_key_bits' => 1024]);
        openssl_pkey_export($resource, $this->privateKey);
        $detail = openssl_pkey_get_details($resource);
        $this->publicKey = $detail['key'];
        file_exists($this->path) ? : mkdir($this->path, 755);
        $this->writeKeys($this->path . $this->publicKey_n, $this->publicKey);
        $this->writeKeys($this->path . $this->privateKey_n, $this->privateKey);
    }

    /**
     * 将密钥对写入 文件
     */
    private function writeKeys ($filePath_s, $key_s) 
    {
        $file = fopen($filePath_s, 'w');
        fwrite($file, $key_s);
        fclose($file);
    }

    /**
     * 公钥加密
     */
    private function publicEncrypt($data)
    {
        openssl_public_encrypt($data, $encrypted, $this->publicKey);
        return $encrypted;
    }
    /**
     * 公钥解密
     */
    private function publicDecrypt($data)
    {
        openssl_public_decrypt($data, $decrypted, $this->publicKey);
        return $decrypted;
    }
    /**
     * 私钥加密
     */
    private function privateEncrypt($data)
    {
        openssl_private_encrypt($data, $encrypted, $this->privateKey);
        return $encrypted;
    }
    /**
     * 私钥解密
     */
    private function privateDecrypt($data)
    {
        openssl_private_decrypt($data, $decrypted, $this->privateKey);
        return $decrypted;
    }

    public function decrypt($data, $type = 'private')
    {
        $type .= 'Decrypt';
        return $this->$type(base64_decode($data));
    }

    public function encrypt($data, $type = 'public')
    {
        $type .= 'Encrypt'; 
        return base64_encode($this->$type($data));
    }
}